/**
  ******************************************************************************
  * @file    GPIO/GPIO_IOToggle/stm32f4xx_it.c 
  * @author  MCD Application Team
  * @version V1.4.0
  * @date    04-August-2014
  * @brief   Main Interrupt Service Routines.
  *          This file provides template for all exceptions handler and 
  *          peripherals interrupt service routine.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_it.h"

#include "cJSON.h"
#include "stdio.h"
#include "led.h"
#include "beep.h"
#include "adc.h"
#include "fan.h"
#include "string.h"

typedef struct Message
 {
     char message_type;		//0--传感器数据和设备状态、1--控制指令
     char message_content[512];
     int sum_check;	//strlen(message_content)//和校验
 }Message;

extern Message message;
extern char message_flag;



extern char key1_status;
extern char key2_status;
extern char key3_status;

extern char mtri_key_value;//矩阵键盘键值
extern char password_input[12];
extern char password[2][12];
extern char password_input_index;
extern char password_pattern;
extern char password_flag;
extern char pwd_change_flag;
extern char input_pwd_change_flag;

u16 tim6_period_cnt;	//按键复用计时器计数值
int usart2_buf_index= 0;// 消息字符串的下标
char usart2_buf[600]={0};// 消息字符串缓冲区

/** @addtogroup STM32F4xx_StdPeriph_Examples
  * @{
  */

/** @addtogroup GPIO_IOToggle
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/******************************************************************************/
/*            Cortex-M4 Processor Exceptions Handlers                         */
/******************************************************************************/

/**
  * @brief   This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
}

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles SVCall exception.
  * @param  None
  * @retval None
  */
//void SVC_Handler(void)
//{
//}

/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}

/**
  * @brief  This function handles PendSVC exception.
  * @param  None
  * @retval None
  */
//void PendSV_Handler(void)
//{
//}

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
//void SysTick_Handler(void)
//{
//}

/******************************************************************************/
/*                 STM32F4xx Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f40xx.s/startup_stm32f427x.s/startup_stm32f429x.s).    */
/******************************************************************************/

/**
  * @brief  This function handles PPP interrupt request.
  * @param  None
  * @retval None
  */
/*void PPP_IRQHandler(void)
{
}*/

/******************************************************************************
函数名：TIM6_DAC_IRQHandler
功能：定时器6中断处理函数---主要用作判断按键消抖判断
输入参数：无
输出参数：无
其他说明：
******************************************************************************/
void TIM6_DAC_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM6, TIM_IT_Update) == SET)
	{
		TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
		tim6_period_cnt++;
	}
}

/*****************************************************************************************
函数名：EXTI4_IRQHandler
功能：外部5-9中断处理函数
输入参数：无
输出参数：无
其他说明：按键1外部中断
*****************************************************************************************/

void EXTI4_IRQHandler(void)
{	
	
	static char key1_flag = 0;
	
	EXTI_ClearITPendingBit(EXTI_Line4);//清除中断标志
	if(key1_flag == 0)
	{
		key1_flag = 1;
		TIM_Cmd(TIM6, ENABLE);//基本定时器6开始计时
	}
	else if(key1_flag == 1)
	{
		key1_flag = 0;
		TIM_Cmd(TIM6, DISABLE);//基本定时器6停止计时
		if(tim6_period_cnt > 6)//超过60ms为有效按下
		{
			key1_status = 1;
		}
		tim6_period_cnt = 0;	
	}
	
}

/*****************************************************************************************
函数名：EXTI9_5_IRQHandler
功能：外部5-9中断处理函数
输入参数：无
输出参数：无
其他说明：按键2-3外部中断
*****************************************************************************************/
void EXTI9_5_IRQHandler(void)
{
	static char key2_flag = 0;
	static char key3_flag = 0;
	
	if(EXTI_GetITStatus(EXTI_Line5) == SET)//判断哪个外部线产生的中断
	{	
		EXTI_ClearITPendingBit(EXTI_Line5);//清除中断标志
		if(key2_flag == 0)
		{
			key2_flag = 1;
			TIM_Cmd(TIM6, ENABLE);//基本定时器6开始计时
		}
		else if(key2_flag == 1)
		{
			key2_flag = 0;
			TIM_Cmd(TIM6, DISABLE);//基本定时器6停止计时
			if(tim6_period_cnt > 6)//超过60ms为有效按下
			{
				key2_status = 1;
			}
			tim6_period_cnt = 0;
		}
	}
	else if(EXTI_GetITStatus(EXTI_Line6) == SET)//判断哪个外部线产生的中断
	{
		EXTI_ClearITPendingBit(EXTI_Line6);//清除中断标志
		if(key3_flag == 0)
		{
			key3_flag = 1;
			TIM_Cmd(TIM6, ENABLE);//基本定时器6开始计时
		}
		else if(key3_flag == 1)
		{
			key3_flag = 0;
			TIM_Cmd(TIM6, DISABLE);//基本定时器6停止计时
			if(tim6_period_cnt > 6 )//高于60ms消抖
			{
				key3_status = 1;
			}
			tim6_period_cnt = 0;
		}
	}
}


/******************************************************************************
函数名：USART2_IRQHandler
功能：串口2中断处理函数,通过WIFI接收JSON数据实现远程控制
输入参数：无
输出参数：无
其他说明：pd5->tx,	pd6->rx
******************************************************************************/

void USART2_IRQHandler(void)
{
	if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)//-------------------接收数据中断
	{
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);	//清除接收中断标志
		USART_SendData(USART1, USART_ReceiveData(USART2));//将串口二接收到的数据通过串口一发送出去
		usart2_buf[usart2_buf_index++] = USART_ReceiveData(USART2);
		
//		if(usart2_buf[0] == '+')
//		{
//			usart2_buf_index++;
//		}
//		else
//		{
//			memset(usart2_buf,0,sizeof(usart2_buf));
//			usart2_buf_index = 0;
//		}		
	}
	if(USART_GetITStatus(USART2, USART_IT_IDLE) == SET)//-------------------总线空闲中断
	{
		USART_ReceiveData(USART2);		//总线空闲中断通过读取数据来清除中断标志
		printf("#%c#%c#%c#%c#%c#%c#",usart2_buf[0],usart2_buf[1],usart2_buf[2],usart2_buf[3],usart2_buf[10],usart2_buf[11]);
		
		//只获取有效数据，防止AT指令被写入buf缓存区
		if(strncmp(usart2_buf+2,"+IPD",4) == 0)
		{	
			message_flag = 1;
			message = *(Message*)(usart2_buf + 13);
			printf("****************************************\n");
			printf("%d\n",message.sum_check);
		}
		//清空接收数据缓冲区，为下次接收做准备
		memset(usart2_buf,0,sizeof(usart2_buf));
		usart2_buf_index = 0;	
	}
}	

/******************************************************************************
函数名：TIM2_IRQHandler
功能：定时器2中断处理函数---定时化任务
输入参数：无
输出参数：无
其他说明：
******************************************************************************/
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
		
		//'#'键确认输入
		if(mtri_key_value == '#')
		{
			if(password_pattern == 0)	//校验密码模式
			{
				if(strcmp(password_input,"***") == 0)
				{
					password_pattern = 1;
					printf("password will be changed,please input super password!\n");
				}
				else if(strcmp(password[0],password_input) == 0 || strcmp(password[1],password_input) == 0)
				{
					printf("password is ok!\n");
					password_flag = 1;
				}
				else
				{
					printf("password is error!\n");
					password_flag = 0;
				}
				
			}
			else if(password_pattern == 1)	//验证管理员密码模式
			{
				if(strcmp(password[0],password_input) == 0)
				{
					password_pattern = 2;
					printf("super password  is ok,pelase input new password\n");
				}
				else
				{
					password_pattern = 0;
					printf("super password  is error,will exit\n");
				}
			}
			else if(password_pattern == 2)	//输入新密码模式
			{
				strcpy(password[1],password_input);
				pwd_change_flag = 1;
				password_pattern = 0;
			}
			//清空输入密码数组、清空输入健值、输入密码数组下标置位。	
			memset(password_input,0,sizeof(password_input));
			input_pwd_change_flag = 1;
			password_input_index = 0;
			mtri_key_value = 0;
		}
	}
}

/**
  * @}
  */ 

/**
  * @}
  */ 


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
